package com.gdd.videos.mini_api.controller;

import com.baomidou.mybatisplus.toolkit.StringUtils;
import com.fasterxml.jackson.databind.ser.std.FileSerializer;
import com.gdd.videos.common.common.GddResult;
import com.gdd.videos.common.common.PagedResult;
import com.gdd.videos.common.common.VideoStatusEnum;
import com.gdd.videos.common.util.FetchVideoVover;
import com.gdd.videos.common.util.MergeVideoBgm;
import com.gdd.videos.mini_api.BasicController;
import com.gdd.videos.pojo.Bgm;
import com.gdd.videos.pojo.Video;
import com.gdd.videos.service.BgmService;
import com.gdd.videos.service.VideoService;
import com.gdd.videos.vo.VideoVo;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.UUID;

/**
 * @author zhangh     
 * @version V1.0.0
 * @projectName parent
 * @title     BgmController   
 * @package    com.gdd.videos.mini_api.controller  
 * @date   2019/9/6 14:02  
 * @explain
 */
@RestController
@RequestMapping("/video")
@Api(value = "小视频接口", tags = "小视频相关的controller")
@Slf4j
@SuppressWarnings("all")
public class VideoController extends BasicController {

    @Autowired
    private BgmService bgmService;

    @Autowired
    private VideoService videoService;

    /**
     * 用户上传小视频
     *
     * @param userId
     * @param file
     * @return
     */
    @ApiOperation(value = "上传视频", notes = "用户上传视频的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "上传视频的用户id", required = true,
                    dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "bgmId", value = "背景音乐id",
                    dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "videoSeconds", value = "视频时常", required = true,
                    dataType = "Double", paramType = "form"),
            @ApiImplicitParam(name = "videoWidth", value = "视频宽度", required = true,
                    dataType = "Integer", paramType = "form"),
            @ApiImplicitParam(name = "videoHeight", value = "视频高度", required = true,
                    dataType = "Integer", paramType = "form"),
            @ApiImplicitParam(name = "desc", value = "视频描述", required = true,
                    dataType = "String", paramType = "form")
    })
    @PostMapping(value = "/uploadVideo", headers = "content-type=multipart/form-data")
    public GddResult uploadVideo(String userId, String bgmId, Double videoSeconds,
                                 Integer videoWidth, Integer videoHeight,
                                 String desc, @RequestParam("file") MultipartFile file) throws Exception {
        System.out.println(fileSpace);

        if (StringUtils.isEmpty(userId)) {
            return GddResult.errorMsg("请先登录");
        }

        FileOutputStream fos = null;
        InputStream ins = null;
        String finalVideoPath = null;
        String finalCoverPath = null;
        // 上传头像保存到数据库中的相对路径
        String filePathDB = "/" + userId + "/video";
        String coverPathDB = "/" + userId + "/cover";
        try {
            if (file != null) {
                // 判断文件名称是否为空
                String filename = file.getOriginalFilename();
                String coverFileNamePre = filename.split("\\.")[0];
                if (StringUtils.isNotEmpty(filename)) {
                    // 文件最终上传保存的路径
                    finalVideoPath = fileSpace + filePathDB + "/" + filename;

                    // 数据库保存路径
                    filePathDB += ("/" + filename);
                    coverPathDB += "/"+coverFileNamePre+".jpg";
                    finalCoverPath = fileSpace + coverPathDB;


                    // 判断目录是否存在,不存在则创建目录,存在则直接存储
                    File outFile = new File(finalVideoPath);
                    if (outFile.getParentFile() == null || !outFile.getParentFile().isDirectory()) {
                        // 创建父文件夹
                        outFile.getParentFile().mkdirs();
                    }

                    File coverOut = new File(finalCoverPath);
                    if (coverOut.getParentFile() == null || !coverOut.getParentFile().isDirectory()) {
                        // 创建父文件夹
                        coverOut.getParentFile().mkdirs();
                    }

                    // 上传截图封面
                    FetchVideoVover ffMpeg = new FetchVideoVover(ffmpegExe);
                    ffMpeg.fetchVideoCover(finalVideoPath, finalCoverPath);

                    // 上传文件(使用apache的IOUtils工具类)
                    fos = new FileOutputStream(outFile);
                    ins = file.getInputStream();
                    IOUtils.copy(ins, fos);
                }
            } else {
                return GddResult.errorMsg("上传失败...");
            }
        } catch (IOException e) {
            e.printStackTrace();
            return GddResult.errorMsg("上传失败...");
        } finally {
            // 释放资源
            if (fos != null) {
                fos.flush();
                fos.close();
            }
            if (ins != null) {
                ins.close();
            }
        }

        // 如果Bgmid不为空,查询出Bgm,合并视频
        if (StringUtils.isNotEmpty(bgmId)) {

            Bgm bgm = bgmService.findById(bgmId);
            MergeVideoBgm mvb = new MergeVideoBgm(ffmpegExe);
            // 输入文件路径
            String inputPaht = finalVideoPath;
            // 背景音乐文件路径
            String bgmPath = fileSpace + bgm.getPath();
            // 输出文件路径
            String outFileName = UUID.randomUUID().toString() + ".mp4";
            filePathDB = "/" + userId + "/video/" + outFileName;
            finalVideoPath = fileSpace + filePathDB;
            mvb.convertor(inputPaht, bgmPath, videoSeconds, finalVideoPath);
        }

        // 将上传的视频信息保存到数据库
        // 封装数据
        Video video = new Video();
        video.setUserId(userId);
        video.setAudioId(bgmId);
        video.setVideoPath(filePathDB);
        video.setVideoSeconds(Float.parseFloat(videoSeconds+""));
        video.setVideoHeight(videoHeight);
        video.setVideoWidth(videoWidth);
        video.setCoverPath(coverPathDB);
        video.setVideoDesc(desc);
        video.setStatus(VideoStatusEnum.SUCCESS.getValue());
        video.setCreateTime(new Date());

        // 保存视频
        String videoId = videoService.saveVideo(video);

        return GddResult.ok(videoId);
    }


    /**
     * 用户上传小封面
     *
     * @param videoId
     * @return
     */
    @ApiOperation(value = "上传视频封面", notes = "用户上传视频封面的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "上传视频的用户id", required = true,
                    dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "videoId", value = "上传封面的videoId", required = true,
                    dataType = "String",paramType = "form")
    })
    @PostMapping(value = "/uploadCover", headers = "content-type=multipart/form-data")
    public GddResult uploadCover(String userId,String videoId,@ApiParam(value = "封面",required = true) MultipartFile file) throws Exception {
        if (StringUtils.isEmpty(videoId) || StringUtils.isEmpty(userId)) {
            return GddResult.errorMsg("视频主键id或用户id不能为空");
        }

        FileOutputStream fos = null;
        InputStream ins = null;
        String finalCoverPath = null;
        // 上传头像保存到数据库中的相对路径
        String filePathDB = "/" + userId + "/cover";
        try {
            if (file != null) {
                // 判断文件名称是否为空
                String filename = file.getOriginalFilename();
                if (StringUtils.isNotEmpty(filename)) {
                    // 文件最终上传保存的路径
                    finalCoverPath = fileSpace + filePathDB + "/" + filename;

                    // 数据库保存路径
                    filePathDB += ("/" + filename);

                    // 判断目录是否存在,不存在则创建目录,存在则直接存储
                    File outFile = new File(finalCoverPath);
                    if (outFile.getParentFile() == null || !outFile.getParentFile().isDirectory()) {
                        // 创建父文件夹
                        outFile.getParentFile().mkdirs();
                    }

                    // 上传文件(使用apache的IOUtils工具类)
                    fos = new FileOutputStream(outFile);
                    ins = file.getInputStream();
                    IOUtils.copy(ins, fos);
                }
            } else {
                return GddResult.errorMsg("上传失败...");
            }
        } catch (IOException e) {
            e.printStackTrace();
            return GddResult.errorMsg("上传失败...");
        } finally {
            // 释放资源
            if (fos != null) {
                fos.flush();
                fos.close();
            }
            if (ins != null){
                ins.close();
            }
        }

        // 将修改的封面保存到数据库
        // 封装封面存储地址信息
        Video video = new Video();
        video.setId(videoId);
        video.setCoverPath(filePathDB);
        videoService.updateVideo(video);

        return GddResult.ok();
    }



    /**
     * 获取所有视频信息列表
     * @return
     */
    @ApiOperation(value = "上传视频封面", notes = "用户上传视频封面的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页", required = true,
                    dataType = "Integer")
    })
    @PostMapping(value = "/showAllVideos")
    public GddResult showAllVideos(Integer page) throws Exception {

        if (page == null){
            page = 1;
        }

        PagedResult<VideoVo> videoList = videoService.getAllVideos(page,pageSize);

        return GddResult.ok(videoList);
    }
}
